﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using MetroFramework.Forms;
using Managistics.Warehouse.Views.Interfaces;
using Managistics.Model;
using Managistics.Warehouse.Controllers.Interfaces;
using Managistics.Warehouse.Factories;
using Managistics.Model.ValueObject;
using BrightIdeasSoftware;
using System.Reflection;
using Managistics.Warehouse.Views.Base;
using Managistics.Core;
using Managistics.Utility.Common.View.NNGrid.Controls;
using Managistics.Utility.Common.View.Components.Test;
using Managistics.Core.Services;
using Managistics.Utility.Common;

namespace Managistics.Warehouse.Views.Purchases
{
    public partial class ViewEnterInputFromPurchase : MetroForm, IViewEnterFromPurchaseView
    {
        private int indexPurchaseOrder = 0;
        private int indexPurchaseOrderDetail = 0;
        private int indexInputSheet = 0;
        private PurchaseOrderParam purchaseOrderParam;
        private string[] listGoodAutocomplete;

        ///
        /// =======================================================================================
        /// Constructure
        /// =======================================================================================
        ///
        public ViewEnterInputFromPurchase()
        {                        
            InitializeComponent();
            InitializeGridPurchaseOrder();
            InitializeGridPurchaseOrderDetail();
            InitializeGridInputSheetDetail();

            InitializeData();
            base.Closed += delegate { Closed(); };
        }

        ///
        /// =======================================================================================
        /// Initialize datas
        /// =======================================================================================
        ///
        private void InitializeData()
        {
            purchaseOrderParam = new PurchaseOrderParam();
            DateTime currentDate = DateTime.Now;
            DateTime startDate = new DateTime(currentDate.Year, currentDate.Month, 1);
            this.metroTextBox1.Text = String.Format("{0:dd/MM/yyyy}", startDate);
            this.metroTextBox2.Text = String.Format("{0:dd/MM/yyyy}", currentDate);
            this.metroTextBox8.Text = String.Format("{0:dd/MM/yyyy}", currentDate);

            List<string> listGoodStr = new List<string>();
            foreach (Good g in GlobalApp.AllGoods)
            {
                listGoodStr.Add(g.Code);
            }
            listGoodAutocomplete = listGoodStr.ToArray();
                        
        }

        ///
        /// =======================================================================================
        /// Implements Actions from IViewEnterFromPurchaseView
        /// =======================================================================================
        ///
        public new event Action Closed = delegate { };
        public event Action<PurchaseOrderParam> LoadPurchaseOrders = delegate { };
        public event Action<string> LoadPurchaseOrderDetails = delegate { };
        public event Action<string> LoadInputSheets = delegate { };
        public event Action<string, string> LoadInputSheetDetails = delegate { };
        public event Action<InputSheetParam> SaveInputSheet = delegate { };
        public event Action<string> DeleteInputSheet = delegate { };

        /// <summary>
        /// show dialog
        /// </summary>
        public void Open()
        {
            ShowDialog();
        }

        /// <summary>
        /// open dialog
        /// </summary>
        /// <param name="view"></param>
        public void Open(IView view)
        {
            this.MdiParent = (Form)view;
            this.WindowState = FormWindowState.Maximized;
            this.Dock = DockStyle.Fill;
            this.Show();
            this.BringToFront();
        }

        ///
        /// =======================================================================================
        /// Controller callback
        /// =======================================================================================
        ///

        /// <summary>
        /// Set PurchaseOrder data
        /// </summary>
        /// <param type="PurchaseOrderRecord" name="record"></param>
        public void SetPurchaseOrderRecord(List<PurchaseOrder> list)
        {
            this.gridPurchaseOrder.SetObjects(list);
        }

        /// <summary>
        /// Set PurchaseOrderDetail data
        /// </summary>
        /// <param type="PurchaseOrderDetailRecord" name="record"></param>
        public void SetPurchaseOrderDetailRecord(List<PurchaseOrderDetail> list)
        {
            this.gridPurchaseOrderDetail.SetObjects(list);
        }

        /// <summary>
        /// Set InputSheet data to InputSheet Combobox
        /// </summary>
        /// <param type="InputSheetRecord" name="record"></param>
        public void SetInputSheetRecord(List<InputSheet> list)
        {
            this.metroComboBox1.DataSource = list;
            if (list != null && list.Count > 0)
            {
                this.metroComboBox1.SelectedIndex = list.Count - 1;
            }            
        }

        /// <summary>
        /// Set InputSheetDetail data
        /// </summary>
        /// <param type="InputSheetDetailRecord" name="record"></param>
        public void SetInputSheetDetailRecord(List<InputSheetDetailRecord> list)
        {
            this.gridInputSheetDetail.SetObjects(list);
        }

        ///
        /// =======================================================================================
        /// Actions View
        /// =======================================================================================
        ///

        private void Search_Click(object sender, EventArgs e)
        {
            this.purchaseOrderParam.StartDate = metroTextBox1.Text;
            this.purchaseOrderParam.EndDate = metroTextBox2.Text;
            this.purchaseOrderParam.Id = metroTextBox3.Text;
            this.purchaseOrderParam.SupplierId = metroTextBox4.Text;
            this.purchaseOrderParam.GoodCode = metroTextBox7.Text;
            this.purchaseOrderParam.GoodName = metroTextBox6.Text;
            this.purchaseOrderParam.SupplierName = metroTextBox5.Text;
            
            LoadPurchaseOrders(this.purchaseOrderParam);
        }

        /// <summary>
        /// Set InputSheet data
        /// </summary>
        /// <param name="purchaseOrder"></param>
        private void SetInputSheetData(PurchaseOrder purchaseOrder)
        {
            this.metroLabel30.Text = purchaseOrder.Orderid;//Purchase Order
            this.metroLabel31.Text = String.Format("{0:dd/MM/yyyy}", purchaseOrder.Orderdate);//Ordered
            this.metroLabel33.Text = String.Format("{0:dd/MM/yyyy}", purchaseOrder.Requestdate);//Requested
            this.metroLabel35.Text = String.Format("{0:dd/MM/yyyy}", purchaseOrder.CompleteDate);//Complated
            this.metroLabel38.Text = purchaseOrder.Supplier.Name;//Supplier
            this.metroTextBox8.Text = String.Format("{0:dd/MM/yyyy}", DateTime.Now);//Inputed Date
        }

        /// <summary>
        /// Onclick on row of PurchaseOrder's grid
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void gridPurchaseOrder_CellClick(object sender, CellClickEventArgs e)
        {
            //System.Diagnostics.Trace.WriteLine(String.Format("clicked ({0}, {1}). model {2}. click count: {3}",
            //    e.RowIndex, e.ColumnIndex, e.Model, e.ClickCount));
            if (gridPurchaseOrder.SelectedObject != null)
            {
                this.indexInputSheet = 0;
                this.indexPurchaseOrderDetail = 0;

                PurchaseOrder purchaseOrder = (PurchaseOrder)gridPurchaseOrder.SelectedObject;
                //Load Purchase Orders detail
                LoadPurchaseOrderDetails(purchaseOrder.Orderid);

                //Set data for Input Sheet
                this.SetInputSheetData(purchaseOrder);
                //Load PurchaseOrder's InputSheets
                this.LoadInputSheets(purchaseOrder.Orderid);
            }
        }

        /// <summary>
        /// Onclick Cancel button
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void metroButton2_Click(object sender, EventArgs e)
        {
            if (metroComboBox1.Items != null && this.metroComboBox1.Items.Count > 0)
            {
                this.metroComboBox1.Enabled = true;
                this.metroComboBox1.SelectedIndex = this.metroComboBox1.Items.Count - 1;
            }
        }

        /// <summary>
        /// Onchange Input Sheets Combobox
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void metroComboBox1_SelectedIndexChanged(object sender, System.EventArgs e)
        {
            ComboBox comboBox = (ComboBox)sender;
            InputSheet selectedItem = (InputSheet)comboBox.SelectedItem;
            if (selectedItem != null && !string.IsNullOrEmpty(this.metroLabel30.Text))
            {
                this.metroTextBox11.Text = selectedItem.DelivererName;
                this.metroTextBox10.Text = selectedItem.ReceiverName;
                this.metroTextBox8.Text = String.Format("{0:dd/MM/yyyy}", selectedItem.InputSheetDate);
                this.metroTextBox9.Text = selectedItem.Note;
                this.LoadInputSheetDetails(this.metroLabel30.Text, selectedItem.InputSheetId);
            }
        }

        /// <summary>
        /// Onclick New Button
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void metroButton3_Click(object sender, EventArgs e)
        {
            this.metroComboBox1.SelectedIndex = 0;
            this.metroComboBox1.Enabled = false;
            DateTime currentDate = DateTime.Now;
            this.metroTextBox8.Text = String.Format("{0:dd/MM/yyyy}", currentDate);
            IList<InputSheetDetailRecord> list = new List<InputSheetDetailRecord>();
            InputSheetDetailRecord newRecord = new InputSheetDetailRecord();
            newRecord.Ordered = currentDate;
            list.Add(newRecord);

            this.gridInputSheetDetail.SetObjects(list);
        }

        /// <summary>
        /// Cell edit starting for InputSheetDetail grid
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void gridInputSheetDetail_EditStarting(object sender, CellEditEventArgs e)
        {
            OLVColumn col = (OLVColumn)e.Column;
            if (col.AspectName == "GoodCode")
            {
                TextBox tb = new TextBox();
                tb.AutoCompleteMode = AutoCompleteMode.SuggestAppend;
                tb.AutoCompleteSource = AutoCompleteSource.CustomSource;
                AutoCompleteStringCollection auto = new AutoCompleteStringCollection();
                auto.AddRange(listGoodAutocomplete);
                tb.AutoCompleteCustomSource = auto;
                tb.Text = (e.Value == null) ? "" : e.Value.ToString();
                tb.Bounds = e.CellBounds;
                tb.Font = ((ObjectListView)sender).Font;
                e.Control = tb;
            }
        }

        /// <summary>
        /// Cell edit finishing for InputSheetDetail grid
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void gridInputSheetDetail_EditFinishing(object sender, CellEditEventArgs e)
        {
            OLVColumn col = (OLVColumn)e.Column;
            if (col.AspectName == "GoodCode")
            {
                InputSheetDetailRecord isDetail = (InputSheetDetailRecord)((ObjectListView)(sender)).SelectedObject;
                if (isDetail != null)
                {
                    string goodCode = (string)e.NewValue; ;
                    foreach (Good good in GlobalApp.AllGoods)
                    {
                        if (goodCode == good.Code)
                        {
                            ((InputSheetDetailRecord)e.RowObject).GoodCode = good.Code;
                            ((InputSheetDetailRecord)e.RowObject).Ordered = ((PurchaseOrder)this.gridPurchaseOrder.SelectedObject).Orderdate;
                            ((InputSheetDetailRecord)e.RowObject).Existing = 0;
                            ((InputSheetDetailRecord)e.RowObject).Unit = good.UnitItem.Name;
                            ((InputSheetDetailRecord)e.RowObject).Name = good.Name;

                            ((ObjectListView)sender).RefreshItem(e.ListViewItem);
                            // We have updated the model object, so we cancel the auto update
                            e.Cancel = true;
                            break;
                        }
                    }
                }
            }
            this.addNewRowGridInputSheetDetail(sender, e);
            ((ObjectListView)(sender)).SelectedItem.Focused = true;

        }

        /// <summary>
        /// Add new row for InputSheetDetail grid
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void addNewRowGridInputSheetDetail(object sender, CellEditEventArgs e)
        {
            int index = (((ObjectListView)(sender)).SelectedItem).Index;
            int end = ((ObjectListView)(sender)).Items.Count - 1;
            InputSheetDetailRecord item = (InputSheetDetailRecord)e.RowObject;
            if (index == end && !string.IsNullOrEmpty(item.GoodCode) && !string.IsNullOrEmpty(item.Input))
            {
                InputSheetDetailRecord newRowObj = new InputSheetDetailRecord();
                this.gridInputSheetDetail.AddObject(newRowObj);
                this.gridInputSheetDetail.EnsureModelVisible(newRowObj);
            }
        }

        /// <summary>
        /// Onclick Save InputSheet
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void metroButton6_Click(object sender, EventArgs e)
        {
            //Set value to PurchaseOrderDetailModel   
            InputSheetParam inpuSheet = new InputSheetParam();
            inpuSheet.PurchaseOrder = (PurchaseOrder)this.gridPurchaseOrder.SelectedObject;
            inpuSheet.InputSheetId = ((InputSheet)this.metroComboBox1.SelectedItem).InputSheetId;
            
            if(string.IsNullOrEmpty(metroTextBox8.Text)) {
                inpuSheet.InputedDate = DateTime.Now;
            }else{
                inpuSheet.InputedDate = DateTimeWithZone.string2DateTime(metroTextBox8.Text);
            }
            inpuSheet.Deliver = metroTextBox11.Text;
            inpuSheet.Receiver = metroTextBox10.Text;
            inpuSheet.Description = metroTextBox9.Text;
            inpuSheet.ListInputSheetDetails = this.gridInputSheetDetail.Objects.Cast<InputSheetDetailRecord>().ToList<InputSheetDetailRecord>();

            this.SaveInputSheet(inpuSheet);
        }

        /// <summary>
        /// Delete an InputSheet
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void metroButton7_Click(object sender, EventArgs e)
        {
            if (this.metroComboBox1.SelectedItem != null && !string.IsNullOrEmpty(((InputSheet)this.metroComboBox1.SelectedItem).InputSheetId))
            {
                DeleteInputSheet(((InputSheet)this.metroComboBox1.SelectedItem).InputSheetId);
            }
        }       
    }
}
